package com.jdone.compus.service;

import com.jdone.compus.dto.BlowDeviceDto;
import com.jdone.compus.dto.BlowDeviceQuery;
import com.jdone.compus.model.BlowDevice;
import com.jdone.compus.repository.BlowDeviceRepository;
import com.jdone.compus.repository.ImeiRecordRepository;
import com.jdone.compus.utils.QRCodeGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.Predicate;
import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;
import java.util.Arrays;

@Service
public class BlowDeviceService {

    @Autowired
    private BlowDeviceRepository blowDeviceRepository;

    @Autowired
    private ImeiRecordRepository imeiRepo;

    /** 根据 DTO 新增或更新 */
    public BlowDevice saveFromDto(BlowDeviceDto dto) throws Exception {
        BlowDevice device = new BlowDevice();
        device.setQrCodeUrl("null");
        BeanUtils.copyProperties(dto, device);
        BlowDevice save = blowDeviceRepository.save(device);

        String qrCodeBase64 = QRCodeGenerator.generateHighDefColoredQRCode(
                String.valueOf(save.getId()),
                800,
                0.35f,
                0xFF004488,
                0xFFFFFFFF
        );

        save.setQrCodeUrl(qrCodeBase64);
        blowDeviceRepository.save(save);
        return save;
    }

    /** 分页多条件查询，过滤掉逻辑删除的记录 */
    public Page<BlowDevice> pageQuery(BlowDeviceQuery q, Pageable pageable) {
        Specification<BlowDevice> spec = (root, query, cb) -> {
            Predicate p = cb.conjunction();

            // 排除已删除的记录
            p = cb.and(p, cb.equal(root.get("isDeleted"), 0));

            if (StringUtils.hasText(q.getName())) {
                p = cb.and(p,
                        cb.like(root.get("name"), "%" + q.getName().trim() + "%"));
            }
            if (StringUtils.hasText(q.getLocation())) {
                p = cb.and(p,
                        cb.like(root.get("location"), "%" + q.getLocation().trim() + "%"));
            }
            if (q.getCreatedFrom() != null) {
                p = cb.and(p,
                        cb.greaterThanOrEqualTo(root.get("createdAt"), q.getCreatedFrom()));
            }
            if (q.getCreatedTo() != null) {
                p = cb.and(p,
                        cb.lessThanOrEqualTo(root.get("createdAt"), q.getCreatedTo()));
            }
            return p;
        };
        return blowDeviceRepository.findAll(spec, pageable);
    }

    /** 根据设备 ID 查询（过滤已删除） */
    public BlowDevice getDeviceById(Long deviceId) {
        return blowDeviceRepository.findByIdAndIsDeleted(deviceId, 0)
                .orElseThrow(() ->
                        new EntityNotFoundException("设备不存在或已被删除，ID=" + deviceId));
    }

    /** 更新设备信息（过滤已删除） */
    public BlowDevice updateFromDto(Long id, BlowDeviceDto dto) {
        BlowDevice entity = blowDeviceRepository.findByIdAndIsDeleted(id, 0)
                .orElseThrow(() -> new EntityNotFoundException("找不到设备或已被删除，ID=" + id));
        copyDtoToEntity(dto, entity);
        return blowDeviceRepository.save(entity);
    }

    /** DTO → Entity 的公共拷贝方法（仅覆盖非空字段） */
    private void copyDtoToEntity(BlowDeviceDto dto, BlowDevice entity) {
        if (StringUtils.hasText(dto.getName())) {
            entity.setName(dto.getName());
        }
        if (StringUtils.hasText(dto.getImei())) {
            entity.setImei(dto.getImei());
        }
        if (StringUtils.hasText(dto.getManufacturer())) {
            entity.setManufacturer(dto.getManufacturer());
        }
        if (dto.getChannel() != null) {
            entity.setChannel(dto.getChannel());
        }
        if (dto.getDeviceType() != null) {
            entity.setDeviceType(dto.getDeviceType());
        }
        if (StringUtils.hasText(dto.getLocation())) {
            entity.setLocation(dto.getLocation());
        }
        if (StringUtils.hasText(dto.getImages())) {
            entity.setImages(dto.getImages());
        }
    }

    /** 批量更新 useTime（过滤已删除） */
    @Transactional
    public int bulkUpdateUseTime(String deviceIdsCsv, String useTime) {
        if (!StringUtils.hasText(deviceIdsCsv)) {
            throw new IllegalArgumentException("deviceIds 不能为空");
        }

        List<Long> ids = Arrays.stream(deviceIdsCsv.split(","))
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .map(s -> {
                    try {
                        return Long.valueOf(s);
                    } catch (NumberFormatException ex) {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        if (ids.isEmpty()) {
            throw new IllegalArgumentException("解析后没有合法的 deviceId");
        }

        // 只更新未删除的设备
        List<Long> validIds = blowDeviceRepository.findByIdInAndIsDeleted(ids, 0)
                .stream()
                .map(BlowDevice::getId)
                .collect(Collectors.toList());

        if (validIds.isEmpty()) {
            return 0;
        }

        return blowDeviceRepository.updateUseTimeByIds(useTime, validIds);
    }

    /** 逻辑删除 */
    @Transactional
    public void logicalDelete(Long id) {
        BlowDevice device = blowDeviceRepository.findByIdAndIsDeleted(id, 0)
                .orElseThrow(() -> new EntityNotFoundException("设备不存在或已删除: " + id));
        device.setIsDeleted(1);
        blowDeviceRepository.save(device);
    }
}
